//package com.open.capacity.filter;
//
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.boot.context.properties.ConfigurationProperties;
//import org.springframework.stereotype.Component;
//
//import javax.servlet.*;
//import javax.servlet.annotation.WebFilter;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//import java.util.List;
//import java.util.regex.Matcher;
//import java.util.regex.Pattern;
//
//@Slf4j
//@Component
//@ConfigurationProperties(prefix = "system.security.csrf")
//@WebFilter(filterName = "CsrfFilter", urlPatterns = "/*")
//public class CsrfFilter implements Filter {
//
//    /**
//     * 过滤器配置对象
//     */
//    FilterConfig filterConfig = null;
//
//    /**
//     * 是否启用
//     */
//    private boolean enable;
//
//    public void setEnable(boolean enable) {
//        this.enable = enable;
//    }
//
//    /**
//     * 忽略的URL
//     */
//    private List<String> excludes;
//
//    public void setExcludes(List<String> excludes) {
//        this.excludes = excludes;
//    }
//
//    /**
//     * 初始化
//     */
//    @Override
//    public void init(FilterConfig filterConfig) throws ServletException {
//        this.filterConfig = filterConfig;
//    }
//
//    /**
//     * 拦截
//     */
//    @Override
//    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
//            throws IOException, ServletException {
//        HttpServletRequest request = (HttpServletRequest) servletRequest;
//        HttpServletResponse response = (HttpServletResponse) servletResponse;
//
//        // 不启用或者已忽略的URL不拦截
//        if (!enable || isExcludeUrl(request.getServletPath())) {
//            filterChain.doFilter(servletRequest, servletResponse);
//            return;
//        }
//
//        String referer = request.getHeader("Referer");
//        String serverName = request.getServerName();
//
//        // 判断是否存在外链请求本站
//        if (null != referer && referer.indexOf(serverName) < 0) {
//            log.error("CSRF过滤器 => 服务器：{} => 当前域名：{}", serverName, referer);
//            servletResponse.setContentType("text/html; charset=utf-8");
//            servletResponse.getWriter().write("系统不支持当前域名的访问！");
//        } else {
//
//            response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
//            response.setHeader("Access-Control-Allow-Methods", "POST, GET");//允许跨域的请求方式
//            response.setHeader("Access-Control-Max-Age", "3600");//预检请求的间隔时间
//            response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token,Access-Control-Allow-Headers");//允许跨域请求携带的请求头
//            response.setHeader("Access-Control-Allow-Credentials","true");//若要返回cookie、携带seesion等信息则将此项设置我true
//
//            response.setHeader("strict-transport-security","max-age=16070400; includeSubDomains");//简称为HSTS。它允许一个HTTPS网站，要求浏览器总是通过HTTPS来访问它
//            //response.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'self'; frame-ancestors 'self'; object-src 'none'");
//            //response.setHeader("X-Content-Type-Options","nosniff");//互联网上的资源有各种类型，通常浏览器会根据响应头的Content-Type字段来分辨它们的类型。通过这个响应头可以禁用浏览器的类型猜测行为
//            response.setHeader("X-XSS-Protection","1; mode=block");//1; mode=block：启用XSS保护，并在检查到XSS攻击时，停止渲染页面
//            response.setHeader("X-Frame-Options","SAMEORIGIN");//SAMEORIGIN：不允许被本域以外的页面嵌入；
//            filterChain.doFilter(servletRequest, servletResponse);
//        }
//    }
//
//    /**
//     * 销毁
//     */
//    @Override
//    public void destroy() {
//        this.filterConfig = null;
//    }
//
//    /**
//     * 判断是否为忽略的URL
//     * @return true-忽略，false-过滤
//     */
//    private boolean isExcludeUrl(String url) {
//        if (excludes == null || excludes.isEmpty()) {
//            return false;
//        }
//        return excludes.stream().map(pattern -> Pattern.compile("^" + pattern)).map(p -> p.matcher(url))
//                .anyMatch(Matcher::find);
//    }
//}